import os
import logging
import errno
import json
import datetime
import math
import pandas as pd
from logging.handlers import RotatingFileHandler
from flask import request, Blueprint
from get_config.index import log_dir


log = Blueprint('log', __name__)


def ensure_dir_exists(directory):
    """
        @function ensure_dir_exists:确保指定的目录存在。如果不存在，则创建它
        @param directory：string 要确保存在的目录路径
        @return 如果目录已存在或成功创建，则返回 True；否则返回 False
    """
    try:
        os.makedirs(directory, exist_ok=True)
        return True
    except OSError as e:
        if e.errno != errno.EEXIST:
            # 如果错误不是“目录已存在”，则记录错误并返回 False
            logging.error(f"创建目录失败 {directory}: {e}")
            return False
        return True  # 目录已存在，返回 True


# 定义一个函数来创建和配置日志记录器
def create_http_logger(status_code, backup_count=1):
    """
        @function create_http_logger:根据HTTP状态码创建一个专门的日志记录器
        @param status_code：int HTTP响应的状态码，用于确定日志级别和日志文件名
        @param backup_count：int(可选) 保留的备份日志文件的数量，默认为1
        @return 配置好的日志记录器对象，如果创建失败则返回 None
    """
    # 根据状态码设置日志级别
    log_level = logging.ERROR if status_code >= 400 else logging.INFO
    # 创建日志记录器
    logger = logging.getLogger(f'http_{status_code}')
    logger.setLevel(log_level)
    # 构造日志文件的路径
    log_file = os.path.join(log_dir, f'{status_code}_log.log')
    # 确保日志目录存在
    if not ensure_dir_exists(log_dir):
        # 如果目录创建失败，则无法继续，返回 None
        return None
    try:
        # 创建一个循环文件处理器
        handler = RotatingFileHandler(log_file, maxBytes=1024 * 1024 * 100, backupCount=backup_count)
        handler.setLevel(log_level)
        # 创建日志格式器并设置给处理器
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s", "%Y-%m-%d %H:%M:%S")
        handler.setFormatter(formatter)
        # 将处理器添加到日志记录器中
        logger.addHandler(handler)
        # 返回配置好的日志记录器对象
        return logger
    except (IOError, OSError) as e:
        # 如果在创建处理器或写入日志时遇到IO错误或OS错误，则记录错误并返回 None
        logging.error(f"未能为创建日志处理程序 {log_file}: {e}")
        return None


save_path = os.path.join(log_dir, 'web_err.xlsx')


@log.route("/upload_logs", methods=['POST'])
def upload_logs():
    # headers = ["用户id", "用户使用的浏览器", "用户的ip地址", "事件id或者报错元素", "完整错误信息", "错误类型", "错误发生的URL", "错误发生的时间", "错误报告时间"]
    headers = ["userUuid", "vendor", "ip", "eventId", "errMessage", "eventType", "triggerPageUrl", "trigger_time", "send_time"]

    get_data = json.loads(request.data.decode('utf-8'))
    base_info = get_data["baseInfo"]
    event_info = get_data["eventInfo"]
    data_list = []
    for index in event_info:
        trigger_time = math.floor(index["triggerTime"] / 1000)
        send_time = math.floor(index["sendTime"] / 1000)
        trigger_time_str = datetime.datetime.fromtimestamp(trigger_time).strftime('%Y-%m-%d %H:%M:%S')
        send_time_str = datetime.datetime.fromtimestamp(send_time).strftime('%Y-%m-%d %H:%M:%S')
        row_array = [
            base_info.get("userUuid", None),
            base_info.get("vendor", None),
            base_info.get("ip", None),
            index.get("eventId", None),
            index.get("errMessage", None),
            index.get("eventType", None),
            index.get("triggerPageUrl", None),
            trigger_time_str,
            send_time_str]
        data_list.append(row_array)
    sheet_name = 'Sheet1'
    try:
        if os.path.exists(save_path):
            new_df = pd.DataFrame(data_list, columns=headers)
            with pd.ExcelWriter(save_path, engine='openpyxl', mode='a', if_sheet_exists='overlay') as writer:
                # 假设目标工作表名为 'Sheet1'
                # 读取现有工作表
                existing_df = pd.read_excel(save_path, sheet_name=sheet_name)
                start_row = len(existing_df) + 1  # 确定现有数据的最后一行
                # 将新数据写入到现有工作表的最后一行之后
                new_df.to_excel(writer, sheet_name=sheet_name, index=False, header=False, startrow=start_row)
        else:
            # 创建新的 DataFrame 并写入文件
            df = pd.DataFrame(data_list, columns=headers)
            df.to_excel(save_path, sheet_name=sheet_name, index=False)
    except Exception as e:
        print(f"File is invalid: {str(e)}")
    return "success"
